package com.yxw.live_vod_backend_boot.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yxw.live_vod_backend_boot.dto.DeptDTO;
import com.yxw.live_vod_backend_boot.dto.DeptIdsDTO;
import com.yxw.live_vod_backend_boot.dto.DeptQueryDTO;
import com.yxw.live_vod_backend_boot.dto.SubsDTO;
import com.yxw.live_vod_backend_boot.entity.YxCsDeptEntity;
import com.yxw.live_vod_backend_boot.mapper.DeptMapper;
import com.yxw.live_vod_backend_boot.service.IDeptService;
import com.yxw.live_vod_backend_boot.vo.DeptTreeItemVO;
import com.yxw.live_vod_backend_boot.vo.DeptVO;
import com.yxw.live_vod_backend_boot.vo.UserEmpVO;
import com.yxw.yxnet_cd_center.common.exception.BaseException;
import com.yxw.yxnet_cd_center.common.utils.BaseDateTime;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 部门管理Service业务层处理
 *
 * @author xiexuxin
 * @date 2023-09-14
 */
@Slf4j
@Service
public class DeptServiceImpl extends ServiceImpl<DeptMapper, YxCsDeptEntity> implements IDeptService {

    @Autowired
    private DeptMapper deptMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addNewDept(DeptDTO deptDTO) {
        log.info("开始处理【添加部门】的业务，参数：{}", deptDTO);
        // 检查部门名称是否已经存在
        LambdaQueryWrapper<YxCsDeptEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(true, YxCsDeptEntity::getDeptName, deptDTO.getDeptName());
        Integer count = deptMapper.selectCount(queryWrapper);
        if (count > 0) {
            throw new BaseException("部门名称【" + deptDTO.getDeptName() + "】已存在，请修改名称");
        }
        // 创建部门实体对象，并复制属性值
        YxCsDeptEntity deptEntity = new YxCsDeptEntity();
        BeanUtils.copyProperties(deptDTO, deptEntity);
        deptEntity.setCreateTime(LocalDateTime.now());
        // 执行插入操作
        int rows = deptMapper.insert(deptEntity);
        // 判断插入操作是否成功
        if (rows != 1) {
            throw new BaseException("添加部门失败，服务器忙，请稍后再尝试！");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addNewSubdivision(SubsDTO subsDTO) {
        log.info("开始处理【添加子部门】的业务,子部门:{}", subsDTO);
        YxCsDeptEntity subsEntity = new YxCsDeptEntity();
        BeanUtils.copyProperties(subsDTO, subsEntity);
        subsEntity.setParentId(subsDTO.getParentId());
        subsEntity.setCreateTime(LocalDateTime.now());
        // 检查是否添加成功
        int rows = deptMapper.insert(subsEntity);
        if (rows != 1) {
            throw new BaseException("添加子部门失败，服务器忙，请稍后再尝试！");
        }
        // 检查子部门名称是否重复
        val existingDept = deptMapper.getDeptByName(subsDTO.getDeptName());
        if (existingDept != null && !existingDept.getDeptName().equals(subsDTO.getDeptName())) {
            throw new BaseException("添加子部门失败，子部门名称重复，请修改后再尝试!");
        }
        // 检查父部门是否存在
        YxCsDeptEntity parentDept = deptMapper.selectById(subsEntity.getParentId());
        if (parentDept == null) {
            throw new BaseException("添加子部门失败，父部门不存在!");
        }
    }

    @Override
    public void deleteByDeptIds(DeptIdsDTO idsDTO) {
        log.info("开始处理【删除部门】的业务，参数：{}", idsDTO);
        if (CollectionUtils.isEmpty(idsDTO.getDeptIds())) {
            throw new BaseException("批量删除部门失败，尝试删除的部门数据不存在！");
        }
        int rows = deptMapper.deleteByDeptIds(idsDTO.getDeptIds());
        if (rows != idsDTO.getDeptIds().size()) {
            throw new BaseException("批量删除部门失败，服务器忙，请稍后再试！");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateInfoById(DeptDTO deptDTO) {
        log.info("开始处理【修改部门】的业务，参数：{}", deptDTO);
        // 查找待修改的部门实体对象
        DeptVO currentDept = deptMapper.getDeptById(deptDTO.getDeptId());
        if (currentDept == null) {
            throw new BaseException("修改部门失败，尝试修改的部门数据不存在！");
        }
        // 检查部门名称是否重复
        LambdaQueryWrapper<YxCsDeptEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(true, YxCsDeptEntity::getDeptName, deptDTO.getDeptName());
        Integer count = deptMapper.selectCount(queryWrapper);
        if (count > 0) {
            throw new BaseException("部门名称【" + deptDTO.getDeptName() + "】已存在，请修改名称");
        }
        // 复制属性值到部门实体对象
        YxCsDeptEntity deptEntity = new YxCsDeptEntity();
        BeanUtils.copyProperties(deptDTO, deptEntity);
        deptEntity.setDeptId(deptDTO.getDeptId());
        deptEntity.setUpdateTime(LocalDateTime.now());
        // 更新部门实体对象
        int rows = deptMapper.updateById(deptEntity);
        if (rows != 1) {
            throw new BaseException("修改部门失败，服务器忙，请稍后再试！");
        }
    }

    @Override
    public DeptVO selectByDeptId(Long deptId) {
        log.info("开始处理【根据部门id查询】的业务，参数：{}", deptId);
        return deptMapper.getDeptById(deptId);
    }

    @Override
    public List<DeptVO> deptList() {
        log.info("开始处理【查询部门列表】的业务，无参数");
        return deptMapper.deptList();
    }

    @Override
    public List<DeptVO> getDeptList(DeptQueryDTO deptQueryDTO) {
        log.info("开始处理【条件查询获取部门树】的业务，参数：无");
        LambdaQueryWrapper<YxCsDeptEntity> queryWrapper = new LambdaQueryWrapper<>();
        // 获取查询条件参数（去除首尾空白）
        String deptName = StringUtils.trimToNull(deptQueryDTO.getDeptName());
        String createDateStart = deptQueryDTO.getCreateTimeStart();
        String createDateEnd = deptQueryDTO.getCreateTimeEnd();
        // 根据传入的条件参数构建查询条件
        queryWrapper
                .like(StringUtils.isNotBlank(deptName), YxCsDeptEntity::getDeptName, deptName)
                .ge(StringUtils.isNotBlank(deptQueryDTO.getCreateTimeStart()), YxCsDeptEntity::getCreateTime, BaseDateTime.getDate(deptQueryDTO.getCreateTimeStart()));
        // 添加创建时间范围条件
        if (StringUtils.isNotBlank(createDateStart) && StringUtils.isNotBlank(createDateEnd)) {
            queryWrapper.apply("DATE(create_time) BETWEEN {0} AND {1}", createDateStart, createDateEnd);
        }
        // 使用baseMapper进行查询
        List<YxCsDeptEntity> entityList = baseMapper.selectList(queryWrapper);
        return BeanUtil.copyToList(entityList, DeptVO.class);
    }

    @Override
    public List<DeptVO> getDeptTree(List<DeptVO> deptVOList) {
        return buildDeptTree(deptVOList);
    }

    @Override
    public List<UserEmpVO> getEmpByDept(DeptIdsDTO deptIds) {
        return deptMapper.getEmpByDeptIds(deptIds.getDeptIds());
    }

    @Override
    public List<DeptTreeItemVO> buildDeptTreeList(List<DeptVO> deptVOList) {
        List<DeptVO> deptTrees = buildDeptTree(deptVOList);
        return deptTrees.stream().map(DeptTreeItemVO::new).collect(Collectors.toList());
    }

    public List<DeptVO> buildDeptTree(List<DeptVO> deptVOList) {
        List<DeptVO> returnList = new ArrayList<>();
        List<Long> tempList = deptVOList.stream().map(YxCsDeptEntity::getDeptId).collect(Collectors.toList());
        for (DeptVO dept : deptVOList) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(dept.getParentId())) {
                recursionFn(deptVOList, dept);
                returnList.add(dept);
            }
        }
        if (returnList.isEmpty()) {
            returnList = deptVOList;
        }
        return returnList;
    }

    /**
     * 递归列表
     * @param list 分类表
     * @param t    子节点
     */
    private void recursionFn(List<DeptVO> list, DeptVO t) {
        List<DeptVO> childList = getChildList(list, t);
        t.setChildren(childList);
        for (DeptVO tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<DeptVO> getChildList(List<DeptVO> list, DeptVO t) {
        List<DeptVO> tlist = new ArrayList<>();
        for (DeptVO n : list) {
            if (n.getParentId().longValue() == t.getDeptId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<DeptVO> list, DeptVO t) {
        return !getChildList(list, t).isEmpty();
    }

}
